package com.tjjingpan.learnkotlin.base

fun <T,R> Collection<T>.fold(
    initial:R,
    combine:(acc:R,nextElement:T) ->R
):R{
    //初始化累加器
    var accumulator:R = initial
    for(element:T in this){
        accumulator = combine(accumulator,element)
    }
    return accumulator
}

fun main(){
    //sampleStart
    val items = listOf(1,2,3,4,5)
    //lambdas表达式是花括号括起来的代码块
    items.fold(0,{
        //如果一个lambda表达式有参的，前面是参数，后跟"->"
        acc:Int,i:Int ->
        print("acc = $acc,i = $i,")
        val result = acc + i
        println("result = $result")
        //lambda表达式中的最后一个表达式是返回值
        result
    })

    //lambda表达式的参数类型是可选的，如果能够推断出来的话:
    val joinedToString =items.fold("Elements:",{ acc,i -> acc + " " +i })

    //按照 Kotlin 惯例，如果函数的最后一个参数是函数，
    // 那么作为相应参数传入的 lambda 表达式可以放在圆括号之外：
    //这种语法也称为拖尾 lambda 表达式。
    val product1 = items.fold(1){acc,e -> acc*e}


    //函数引用也可以用于高阶函数调用
    val product = items.fold(1,Int::times)
    //sampleEnd
    println("joinedToString = $joinedToString")
    println("product =$product")
    println("product1 =$product1")

}